package com.mxpio.erp.plan.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.mxpio.erp.common.enums.CommonEnums;
import com.mxpio.erp.common.enums.OrderStatusEnums;
import com.mxpio.erp.common.enums.PlanEnums;
import com.mxpio.erp.common.plan.entity.*;
import com.mxpio.erp.common.plan.service.MpsLineTempService;
import com.mxpio.erp.common.plan.service.MpsVersionTempService;
import com.mxpioframework.common.util.BeanReflectionUtils;
import com.mxpioframework.common.util.SpringUtil;
import com.mxpioframework.jpa.policy.impl.CrudType;
import com.mxpioframework.system.service.SnRuleService;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.mxpio.erp.common.enums.OrderStatusEnums.BpmnStatus;
import com.mxpio.erp.common.plan.service.MpsVersionService;
import com.mxpio.erp.common.sales.entity.SalesOrderLine;
import com.mxpioframework.common.vo.Result;
import com.mxpioframework.jpa.JpaUtil;
import com.mxpioframework.jpa.query.Criteria;
import com.mxpioframework.jpa.query.Operator;
import com.mxpioframework.jpa.query.Order;
import com.mxpioframework.security.util.SecurityUtils;
import com.mxpioframework.system.service.impl.BaseServiceImpl;

@Service
public class MpsVersionServiceImpl extends BaseServiceImpl<MpsVersion> implements MpsVersionService {

	@Autowired
	private MpsLineTempService mpsLineTempService;
	@Autowired
	private MpsVersionTempService mpsVersionTempService;
	@Override
	@Transactional(readOnly = true)
	public Boolean saveOnCheck(MpsVersion mpsVersion) {
		if(mpsVersion.getType().equals(PlanEnums.PlanType.DYNAMIC.getCode())){
			return true;
		}
		if(mpsVersion.getEndDate().before(mpsVersion.getStartDate())){
			return false;
		}
		Criteria criteria = Criteria.create();
		// 判断日期
		criteria.addCriterion("endDate", Operator.GE, mpsVersion.getStartDate());
		// 如果是修改，则排除原数据判断日期
		if(mpsVersion.getCode() != null){
			criteria.addCriterion("code", Operator.NE, mpsVersion.getCode());
		}
		long count = JpaUtil.linq(MpsVersion.class).where(criteria).list().size();
		if(count == 0){
			//save(mpsVersion);//只校验，不保存
			return true;
		}
		return false;
	}
	
	@Override
	@Transactional(readOnly = true)
	public Page<SalesOrderLine> poLinePageWithoutMps(Pageable page, Criteria criteria,String versionCode) {
		List<Order> orders = new ArrayList<Order>();
		if(criteria != null){
			orders = criteria.getOrders();
		}
		return JpaUtil
				.linq(SalesOrderLine.class)
				.where(criteria)
				.notExists(MpsLine.class)
					.equalProperty("bizNo", "bizNo")
					.equalProperty("bizLineNo", "lineNo")
					.equal("versionCode",versionCode)
				.end()
				.addIfNot(orders)
					.desc("createTime")
				.endIf()
				.paging(page);
	}

	@Override
	@Transactional(readOnly = true)
	public Page<SalesOrderLine> poLinePage(Pageable page, Criteria criteria) {
		List<Order> orders = new ArrayList<Order>();
		if(criteria != null){
			orders = criteria.getOrders();
		}
		return JpaUtil
				.linq(SalesOrderLine.class)
				.where(criteria)
				/*.notExists(MpsLine.class)
				.equalProperty("bizNo", "bizNo")
				.equalProperty("bizLineNo", "lineNo")
				.end()*/
				.addIfNot(orders)
				.desc("createTime")
				.endIf()
				.paging(page);
	}
	
	@Override
	@Transactional(readOnly = false)
	public Result<MpsVersion> updateBpmnStatus(MpsVersion mpsVersion, BpmnStatus bpmnStatus) {
		mpsVersion.setBpmnStatus(bpmnStatus.getStatusCode());
		if (bpmnStatus.getStatusCode().equals(BpmnStatus.AUDITED.getStatusCode())){//审核通过时，才写入审核人和时间
			mpsVersion.setReviewer(SecurityUtils.getLoginUsername());
			mpsVersion.setReviewTime(new Date());
		}
        this.update(mpsVersion);
        return Result.OK(mpsVersion);
	}


	@Override
	@Transactional(readOnly = true)
	public Page<OrganizationDemandLine> odLinePageWithoutMps(Pageable page, Criteria criteria,String versionCode) {
		List<Order> orders = new ArrayList<Order>();
		if(criteria != null){
			orders = criteria.getOrders();
		}
		return JpaUtil
				.linq(OrganizationDemandLine.class)
				.where(criteria)
				.exists(OrganizationDemand.class)
					.equalProperty("bizNo", "bizNo")
					.equal("bpmnStatus", OrderStatusEnums.BpmnStatus.AUDITED.getStatusCode())
				.end()
				.notExists(MpsLine.class)
					.equalProperty("bizNo", "bizNo")
					.equalProperty("bizLineNo", "lineNo")
					.equal("versionCode",versionCode)
				.end()
				.addIfNot(orders)
					.desc("createTime")
				.endIf()
				.paging(page);
	}

	@Override
	@Transactional(readOnly = true)//销售预测未关联计划明细行
	public Page<SalePredictionLine> spLinePageWithoutMps(Pageable page, Criteria criteria, String versionCode) {
		List<Order> orders = new ArrayList<Order>();
		if(criteria != null){
			orders = criteria.getOrders();
		}
		return JpaUtil
				.linq(SalePredictionLine.class)
				.where(criteria)
				.exists(SalePrediction.class)
				.equalProperty("bizNo", "bizNo")
				.equal("bpmnStatus", OrderStatusEnums.BpmnStatus.AUDITED.getStatusCode())
				.end()
				.notExists(MpsLine.class)
				.equalProperty("bizNo", "bizNo")
				.equalProperty("bizLineNo", "lineNo")
				.equal("versionCode",versionCode)
				.end()
				.addIfNot(orders)
				.desc("createTime")
				.endIf()
				.paging(page);
	}
	@Override
	@Transactional(readOnly = true)
	public Page<OrganizationDemandLine> odLinePage(Pageable page, Criteria criteria) {
		List<Order> orders = new ArrayList<Order>();
		if(criteria != null){
			orders = criteria.getOrders();
		}
		return JpaUtil
				.linq(OrganizationDemandLine.class)
				.where(criteria)
				.exists(OrganizationDemand.class)
					.equalProperty("bizNo", "bizNo")
					.equal("bpmnStatus", OrderStatusEnums.BpmnStatus.AUDITED.getStatusCode())
				.end()
				.addIfNot(orders)
				.desc("createTime")
				.endIf()
				.paging(page);
	}
	@Override
	@Transactional(readOnly = false)
	public void copyToTemp(MpsVersion mpsVersion){
		SnRuleService snRuleService = SpringUtil.getBean(SnRuleService.class);
		String expression = "MPSC";
		String yearmonth = DateUtils.formatDate(new Date(), "yyyyMMdd");
		String bizNo = (String) snRuleService.execute(expression+yearmonth+"####", null);
		MpsVersionTemp mpsVersionTemp = new MpsVersionTemp();
		BeanReflectionUtils.copyProperties(mpsVersionTemp,mpsVersion);
		mpsVersionTemp.setBpmnStatus(BpmnStatus.AUDITING.getStatusCode());
		mpsVersionTemp.setReviewOpinion("");
		mpsVersionTemp.setReviewer("");
		mpsVersionTemp.setReviewTime(null);//清空之前审核结果数据
		mpsVersionTemp.setCrudType(CrudType.SAVE);
		mpsVersionTemp.setId(bizNo);
		mpsVersionTempService.save(mpsVersionTemp);
		List<MpsLine> mpsLines = mpsVersion.getMpsLineList();
		if (mpsLines.size()>0){
			String ylexpression = "YL";
			String ylyearmonth = DateUtils.formatDate(new Date(), "yyyyMMdd");
			for (MpsLine line:mpsLines){
				if (CrudType.DELETE.equals(line.getCrudType())){
					continue;
				}
				if (line.getDataType().equals("03")&& StringUtils.isBlank(line.getBizNo())){//如果是本次新增的数据，需要生成
					String ylbizNo = (String) snRuleService.execute(ylexpression+ylyearmonth+"###", null);
					line.setBizNo(ylbizNo);
					line.setBizLineNo("1");
				}
				MpsLineTemp mpsLineTemp = new MpsLineTemp();
				BeanReflectionUtils.copyProperties(mpsLineTemp,line);
				mpsLineTemp.setId(null);
				mpsLineTemp.setPid(mpsVersionTemp.getId());
				mpsLineTemp.setVersionCode(mpsVersionTemp.getCode());
				mpsLineTemp.setCrudType(CrudType.SAVE);
				mpsLineTempService.save(mpsLineTemp);
			}
		}
	}

	@Override
	@Transactional(readOnly = false)
	public Result<MpsVersion> updateEffectiveStatus(MpsVersion mpsVersion, CommonEnums.EffectiveStatus yes) {
		List<MpsVersion> effectiveYesMpsVersions = JpaUtil.linq(MpsVersion.class).equal("effectiveStatus", CommonEnums.EffectiveStatus.YES.getCode()).list();
		if (effectiveYesMpsVersions.size()>0){
			effectiveYesMpsVersions.forEach(dbVersion->dbVersion.setEffectiveStatus(CommonEnums.EffectiveStatus.NO.getCode()));
			update(effectiveYesMpsVersions);//
		}
		mpsVersion.setEffectiveStatus(CommonEnums.EffectiveStatus.YES.getCode());//生效
		this.update(mpsVersion);
		return Result.OK(mpsVersion);
	}
}
